package com.ojoin.trade.common.utils;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.ServletContext;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.validation.ConstraintViolation;
import javax.validation.Validation;
import javax.validation.Validator;
import javax.validation.ValidatorFactory;

import org.apache.commons.beanutils.ConvertUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Hex;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.fileupload.FileUploadBase;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.ClassUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.UnavailableSecurityManagerException;
import org.apache.shiro.session.InvalidSessionException;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import com.ojoin.trade.common.Constants;
import com.ojoin.trade.common.RepCode;
import com.ojoin.trade.common.exception.BusinessException;
import com.ojoin.trade.common.exception.ControllerException;
import com.ojoin.trade.common.utils.json.JSONUtils;
import com.ojoin.trade.common.web.domain.Pair;
import com.ojoin.trade.common.web.domain.Result;
import com.ojoin.trade.common.web.domain.Result.Status;
import com.ojoin.trade.common.web.domain.SessionUser;
import com.ojoin.trade.common.web.domain.User;
import com.ojoin.trade.common.web.service.impl.UserUtils;
import com.ojoin.trade.common.web.shiro.Principal;

public class CommonUtils {
	
	private static Logger log = LoggerFactory
			.getLogger(CommonUtils.class);
	
	private static final String[] NUM = new String[] { "0", "1", "2", "3", "4",
			"5", "6", "7", "8", "9", "." };

	private static final Pattern KVP_PATTERN = Pattern.compile("([_.a-zA-Z0-9][-_.a-zA-Z0-9]*)[=](.*)"); //key value pair pattern.

	// 静态文件后缀
	private final static String[] staticFiles = StringUtils.split(Config.getProperty("sysConfig","web.staticFile"), ",");

	
    /**
     * 转换为字节数组
     * @param str
     * @return
     */
    public static byte[] getBytes(String str){
    	if (str != null){
    		try {
				return str.getBytes(Constants.ENCODING);
			} catch (UnsupportedEncodingException e) {
				return null;
			}
    	}else{
    		return null;
    	}
    }

    public static boolean isDev(){
        String environment = Config.getProperty("sys.mode");
        return "development".equals(environment);
    }
   public static boolean expireTime(){
       String time= TimeUtils.getCurTime();
       if(time.compareTo("15:00:00")>0){
           return false;
       }
       return true;


    }
	public static boolean isEmpty(Object value) {
		if (value == null)
			return true;
		if ((value instanceof String)
				&& (((String) value).trim().length() <= 0))
			return true;
		if ((value instanceof Object[]) && (((Object[]) value).length <= 0))
			return true;
		if ((value instanceof Collection) && ((Collection) value).size() <= 0)
			return true;
		if ((value instanceof Dictionary) && ((Dictionary) value).size() <= 0)
			return true;
		return false;
	}

	public static boolean isEqual(Object o1, Object o2) {
		if (isEmpty(o1) && isEmpty(o2))
			return true;
		if (isEmpty(o1) && !isEmpty(o2))
			return false;
		if (!isEmpty(o1) && isEmpty(o2))
			return false;
		return o1.toString().trim().equalsIgnoreCase(o2.toString().trim());
	}

	/**
	 * 判断字符串为数字
	 * 
	 * @param src
	 * @return
	 */
	public static boolean isNum(String src) {
		if (CommonUtils.isEmpty(src))
			return true;
		char[] cs = src.toCharArray();
		for (int i = 0; i < cs.length; i++) {
			boolean isNum = false;
			for (int j = 0; j < NUM.length; j++) {
				if (CommonUtils.isEqual(cs[i], NUM[j].toCharArray()[0])) {
					isNum = true;
					break;
				}
			}
			if (!isNum) {
				return false;
			}
		}
		return true;
	}

	/**
	 * 判断字符串由数字和.构成，可能是数字，也可能是IP地址等
	 * 
	 * @param src
	 * @return
	 */
	public static boolean isNum1(String src) {
		if (CommonUtils.isEmpty(src)) {
			return true;
		}
		return src.matches("-?(\\d+\\.)?\\d+");

	}

	public static double getdouble(String src) {
		if (src == null || src.length() == 0)
			return 0.0;
		return Double.valueOf(src);
	}

//	public static Double getDouble(String src) {
//		if (src == null || src.length() == 0)
//			return 0.0;
//		return Double.valueOf(src);
//	}
	
	public static int getInt(String src) {
		if (src == null || src.length() == 0)
			return 0;
		return Integer.valueOf(src);
	}

    /**
     *专门为放款的id做转换
     *  * @param src
     * @return
     */
    public static Integer getInteger(String src){
        if ("-1".equals(src)){
            return null;
        }
        return Integer.valueOf(src);
    }

	public static long getLong(String src) {
		if (src == null || src.length() == 0)
			return 0;
		if(src.endsWith(".00")){
			src=src.substring(0,src.indexOf(".00"));
		}
		return Long.valueOf(src);
	}
	
	public static String getString(int src) {
		return Integer.toString(src);

	}
	
	public static String getString(double src) {
		return Double.toString(src);
	}
	
	public static String getString(long src) {
		return Long.toString(src);

	}


	public static boolean isInterface(Class c, String szInterface) {
		Class[] face = c.getInterfaces();
		for (int i = 0, j = face.length; i < j; i++) {
			if (face[i].getName().equals(szInterface)) {
				return true;
			} else {
				Class[] face1 = face[i].getInterfaces();
				for (int x = 0; x < face1.length; x++) {
					if (face1[x].getName().equals(szInterface)) {
						return true;
					} else if (isInterface(face1[x], szInterface)) {
						return true;
					}
				}
			}
		}
		if (null != c.getSuperclass()) {
			return isInterface(c.getSuperclass(), szInterface);
		}
		return false;
	}

	public static String[] getFldsByDDL(String strTblDDL) {
		if (CommonUtils.isEmpty(strTblDDL))
			return new String[0];
		strTblDDL = strTblDDL.trim().replace("\"", "");
		String subStr = strTblDDL.substring(strTblDDL.indexOf("(") + 1,
				strTblDDL.lastIndexOf(")") - 1);
		StringTokenizer st = new StringTokenizer(subStr, ",");
		ArrayList<String> al = new ArrayList<String>();
		StringTokenizer stsub = null;
		while (st.hasMoreTokens()) {
			String ele = st.nextToken();
			if (CommonUtils.isEmpty(ele))
				continue;
			stsub = new StringTokenizer(ele);
			if (stsub.countTokens() > 2)
				continue;
			if (stsub.hasMoreTokens()) {
				al.add(stsub.nextToken().trim());
			}
		}
		return al.toArray(new String[al.size()]);
	}


	public static  String dup(String placeholder,int count){
		String ret="";
		for(int i=0;i<count;i++){
			ret+=placeholder;
		}
		return ret;
	}
	
	
	public static Object[] pack(String[] objs) {
		if (CommonUtils.isEmpty(objs))
			return new String[0];
		ArrayList<String> al = new ArrayList<String>();
		for (int i = 0; i < objs.length; i++) {
			if (objs[i] != null)
				al.add(objs[i]);
		}
		return al.toArray(new String[] {});
	}

	public static String getFileContent(String filename) throws Exception {
		InputStreamReader input = null;
		LineNumberReader lineReader = null;
		try {
			input = new InputStreamReader(new BufferedInputStream(
					new FileInputStream(filename)),Constants.ENCODING);
			lineReader = new LineNumberReader(input);
			String curline = null;
			StringBuffer sb = new StringBuffer();
			while ((curline = lineReader.readLine()) != null) {
				sb.append(curline).append("\n");
			}
			return sb.toString();
		} finally {
			try {
				input.close();
			} catch (Exception e) {

			}
			try {
				lineReader.close();
			} catch (Exception e) {

			}
		}
	}

	public static void sort(Object o, Comparator comparator) {
		if (o instanceof Object[]) {
			Arrays.sort((Object[]) o, comparator);
		} else if (o instanceof List) {
			Collections.sort((List) o, comparator);
		}
	}

	public static void delDir(String dirName) {
		File file = new File(dirName);
		if (file.isDirectory()) {
			File[] files = file.listFiles();
			files = (files == null ? new File[0] : files);
			for (int i = 0; i < files.length; i++) {
				if (files[i].isDirectory()) {
					delDir(files[i].getAbsolutePath());
				} else {
					try {
						files[i].delete();
					} catch (Exception e) {

					}
				}
			}
			try {
				file.delete();
			} catch (Exception e) {

			}
		} else {
			try {
				file.delete();
			} catch (Exception e) {

			}
		}
	}

	public static String getWherePartByKeys(String fld, String[] arsKey) {
		final int MAX = 500;
		if (isEmpty(arsKey))
			return " 1 = 1 ";
		if (arsKey.length == 1)
			return fld + "='" + arsKey[0] + "'";
		if (arsKey.length <= MAX) {
			String sTmp = fld + " in (";
			for (int i = 0; i < arsKey.length; i++) {
				if (i == arsKey.length - 1) {
					sTmp += "'" + arsKey[i] + "')";
					break;
				}
				sTmp += "'" + arsKey[i] + "',";
			}
			return sTmp;
		}
		int ipos = 0;
		int itimes = arsKey.length / MAX;
		int mode = arsKey.length % MAX;
		String where = null;
		for (int i = 0; i < itimes; i++) {
			if (where == null)
				where = " ( " + fld + " in ( ";
			else
				where += " or " + fld + " in (";
			for (int j = 0; j < MAX; j++) {
				if (j == MAX - 1) {
					where += "'" + arsKey[ipos + j] + "')";
					break;
				}
				where += "'" + arsKey[ipos + j] + "',";
			}
			ipos += MAX;
		}
		if (mode == 0)
			where += " )";
		else {
			where += " or " + fld + " in (";
			for (int k = 0; k < mode; k++) {
				if (k == mode - 1) {
					where += "'" + arsKey[ipos + k] + "'))";
					break;
				}
				where += "'" + arsKey[ipos + k] + "',";
			}
		}
		return where;
	}

	public static byte[] getFileBytes(String filename) {
		FileInputStream fis = null;
		ByteArrayOutputStream bos = new ByteArrayOutputStream();
		try {
			fis = new FileInputStream(new File(filename));
			byte[] buf = new byte[1024];
			int i = 0;
			while ((i = fis.read(buf)) != -1) {
				bos.write(buf, 0, i);
			}
			return bos.toByteArray();
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				fis.close();
			} catch (Exception e) {

			}
			try {
				bos.close();
			} catch (Exception e) {
			}
		}
		return null;
	}

	public static void writeFile(String filename, byte[] bs) {
		if (CommonUtils.isEmpty(bs))
			return;
		File file = new File(filename);
		if (!file.getParentFile().exists())
			file.getParentFile().mkdirs();
		if (!file.exists()) {
			try {
				file.createNewFile();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		FileOutputStream fos = null;
		try {
			fos = new FileOutputStream(new File(filename));
			fos.write(bs);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				fos.close();
			} catch (Exception e) {

			}
		}
	}

	public static String utf8Togb2312(String str) {

		StringBuffer sb = new StringBuffer();

		for (int i = 0; i < str.length(); i++) {

			char c = str.charAt(i);

			switch (c) {

			case '+':

				sb.append(' ');

				break;

			case '%':

				try {

					sb.append((char) Integer.parseInt(

					str.substring(i + 1, i + 3), 16));

				}

				catch (NumberFormatException e) {

					throw new IllegalArgumentException();

				}

				i += 2;

				break;

			default:

				sb.append(c);

				break;

			}

		}

		String result = sb.toString();

		String res = null;

		try {

			byte[] inputBytes = result.getBytes("8859_1");

			res = new String(inputBytes, Constants.ENCODING);

		}

		catch (Exception e) {
		}

		return res;

	}

	public static int getTotalLine(String txt) {
		if (CommonUtils.isEmpty(txt))
			return -1;
		int ipos = txt.indexOf("\n");
		int count = 0;
		while (ipos > -1) {
			count++;
			ipos = txt.indexOf("\n", ipos + 1);
		}
		return count;
	}

	public static int getLineAt(String txt, String chars) {
		if (CommonUtils.isEmpty(chars))
			return -1;
		int ipos = txt.indexOf(chars);
		if (ipos < 0)
			return -1;
		int iipos = txt.indexOf("\n");
		if (iipos < 0)
			return 0;
		int count = 0;
		while (iipos < ipos) {
			count++;
			iipos = txt.indexOf("\n", iipos + 1);
		}
		return count;
	}

	public static String getExceptionStack(Exception e) {
		StringWriter sw = new StringWriter();
		PrintWriter pw = new PrintWriter(sw);
		e.printStackTrace(pw);
		String stackTrace = sw.toString();
		return stackTrace;
	}

	public static String byte2hex(String s)
	{
		byte[] b=null;
		try {
			b = s.getBytes(Constants.ENCODING);
		} catch (UnsupportedEncodingException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		if (b == null || b.length == 0)
			return "0x0";
		String hs = "0x";
		String stmp = "";
		for (int n = 0; n < b.length; n++) {
			stmp = (java.lang.Integer.toHexString(b[n] & 0XFF));
			if (stmp.length() == 1)
				hs = hs + "0" + stmp;
			else
				hs = hs + stmp;
		}
		return hs;
	}

	public static String hex2String(String str) {
		if (str == null) {
			return null;
		}

		str = str.trim();

		if (str.startsWith("0x")) {
			str = str.substring(2);
		}
		int len = str.length();

		if ((len & 0x1) != 0) {
			return null;
		}
		byte[] b = new byte[len / 2];
		try {
			for (int i = 0; i < str.length(); i += 2) {
				b[(i / 2)] = (byte) Integer.decode(
						"0x" + str.substring(i, i + 2)).intValue();
			}

			return new String(b,Constants.ENCODING);
		} catch (Exception e) {
		}
		return null;
	}


	public static void copyFiles2Dir(String filePath, String destDir) {
		DataInputStream inputStream = null;
		FileOutputStream outputStream = null;
		File srcFile = new File(filePath);
		File destFile = new File(destDir);
		File newFile = new File(destFile + "/" + srcFile.getName());
		try {
			inputStream = new DataInputStream(new FileInputStream(srcFile));
			if (!destFile.exists())
				destFile.mkdirs();
			outputStream = new FileOutputStream(newFile);
			byte[] buf = new byte[8192];
			while (true) {
				int read = 0;
				if (inputStream != null) {
					read = inputStream.read(buf);
				}

				if (read == -1) {
					break;
				}
				outputStream.write(buf, 0, read);
			}
		} catch (Exception e) {
			e.printStackTrace();
			return;
		} finally {
			try {
				outputStream.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
			try {
				inputStream.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		newFile.setLastModified(srcFile.lastModified());
	}
	
	/**
	 * 是否成功
	 * @param list 还回数据集
	 * @return
	 */
	public static boolean isSuccess(List list) {
		if (CollectionUtils.isNotEmpty(list) && list.size() >= 2) {
			String first = (String) list.get(0);
			if ("00".equals(first)) {
				Map<String, String> data = (Map) list.get(1);
				String responseCode = data.get("responseCode");
				return RepCode.SUCCESS.getCode().equals(responseCode);
			} else {
				return false;
			}
		}
		return false;
	}
	
	/**
	 * 是否处理中（如转账操作返回的状态码为处理中，业务继续处理不抛错，后台需要对该记录跟踪处理，待账户体系转账成功后，补做一次转账操作）
	 * @param list 还回数据集
	 * @return
	 */
	public static boolean isProcessing(List list) {
		if (CollectionUtils.isNotEmpty(list) && list.size() >= 2) {
			String first = (String) list.get(0);
			if ("00".equals(first)) {
				Map<String, String> data = (Map) list.get(1);
				String responseCode = data.get("responseCode");
				return RepCode.PROCESSING.getCode().equals(responseCode);
			} else {
				return false;
			}
		}
		return false;
	}
	/**
	 * 接口调用错误处理
	 * @param list
	 * @return
	 */
	public static Result buildError(List list) {
		String message=null;
		if (CollectionUtils.isNotEmpty(list) && list.size() >= 2) {
			if("00".equals(list.get(0))){
				Map<String, String> data = (Map) list.get(1);
				message=data.get(Constants.IPAYNOW_KEY_RESPONSEMSG);
			}else{
				message=(String)list.get(1);
				Map msgMap=null;
				try{
					if(StringUtils.isNotBlank(message)&&(message.indexOf("{")>0||message.indexOf("[")>0)){
						msgMap=JSONUtils.parseObject(message, Map.class);
					}
				}catch(Exception e){
					//ignore 
				}
				if(null!=msgMap){
				   String msg=(String)msgMap.get(Constants.IPAYNOW_KEY_RESPONSEMSG);
				   if(StringUtils.isNotEmpty(msg)){
					   message=msg; 
				   }
				}
			}
		}
		if (StringUtils.isEmpty(message)) {
			message = "未知错误,请联系九盈科技工作人员";
		}
		return new Result(Status.ERROR,message);
	}
	
	
	public static String getStrByIDs(int[] ids) {
		if (ids == null || ids.length == 0)
			return null;
		
		StringBuffer strbf = new StringBuffer();
		int i = 0;
		for(int id : ids) {
			if (i > 0)
				strbf.append(", ");
			strbf.append(id);
			i++;
		}
		
		return strbf.toString();
	}
	
	public static String getStrByIDs(ArrayList<Integer> idlist) {
		if (idlist == null || idlist.size() == 0)
			return null;
		
		Integer[] ids = idlist.toArray(new Integer[0]);
		StringBuffer strbf = new StringBuffer();
		int i = 0;
		for(Integer id : ids) {
			if (i > 0)
				strbf.append(", ");
			strbf.append(id);
			i++;
		}
		
		return strbf.toString();
	}
	
	
	
	/**
	 * cookie 移除
	 * @param response
	 * @param key
	 */
	public static void removeCookie(HttpServletResponse response, String key){
		Cookie cookie = new Cookie(key, "");
		cookie.setMaxAge(0);
		cookie.setPath("/");
		response.addCookie(cookie);
	}
	 
	/**
	 * 设置 Cookie（生成时间为1天）
	 * @param name 名称
	 * @param value 值
	 */
	public static void setCookie(HttpServletResponse response, String name, String value) {
		setCookie(response, name, value, 60*60*24);
	}
	
	/**
	 * 设置 Cookie
	 * @param name 名称
	 * @param value 值
	 * @param path 路径
	 */
	public static void setCookie(HttpServletResponse response, String name, String value, String path) {
		setCookie(response, name, value, path, 60*60*24);
	}
	
	/**
	 * 设置 Cookie
	 * @param name 名称
	 * @param value 值
	 * @param maxAge 生存时间（单位秒）
	 */
	public static void setCookie(HttpServletResponse response, String name, String value, int maxAge) {
		setCookie(response, name, value, "/", maxAge);
	}
	
	/**
	 * 设置 Cookie
	 * @param name 名称
	 * @param value 值
	 * @param maxAge 生存时间（单位秒）
	 */
	public static void setCookie(HttpServletResponse response, String name, String value, String path, int maxAge) {
		Cookie cookie = new Cookie(name, null);
		cookie.setPath(path);
		cookie.setMaxAge(maxAge);
		try {
			cookie.setValue(URLEncoder.encode(value, Constants.ENCODING));
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		response.addCookie(cookie);
	}
	
	/**
	 * 字符串首字母小写
	 * @param str
	 * @return
	 */
	public static String toLowerCaseFirstOne(String str) {
		if (str == null || "".equals(str))
			return str;
		if (Character.isLowerCase(str.charAt(0)))
			return str;
		else
			return (new StringBuilder()).append(Character.toLowerCase(str.charAt(0))).append(str.substring(1))
					.toString();
	}

	/**
	 * 字符串首字母大写
	 * @param str
	 * @return
	 */
	public static String toUpperCaseFirstOne(String str) {
		if (str == null || "".equals(str))
			return str;
		if (Character.isUpperCase(str.charAt(0)))
			return str;
		else
			return (new StringBuilder()).append(Character.toUpperCase(str.charAt(0))).append(str.substring(1))
					.toString();
	}

    /**
     *
     * @param iterable
     * @param <T>
     * @return
     */
	public static <T> List<T> cast(Iterable<T> iterable) {
		List<T> ret=new ArrayList<T>();
		if(null!=iterable){
			Iterator<T> iterator=iterable.iterator();
			while (iterator.hasNext()) {
				ret.add(iterator.next());
			}
		}
		return ret;
	}
	
	
	/**
	 * 泛型,对象转换方法
	 * @param src
	 * @return
	 */
	public static <T> T cast(Object src){
		return  (T)src;
	}
	
	 
	/**
	 *  @param context : request.getSession().getServletContext();
	  * 获取web服务器路径,兼容tomcat和weblogic(war)
	  * @return
	  */
	 public static String getContextRootPath(ServletContext context){
			String rootpath=context.getRealPath("/");
			try {
				if(null==rootpath){
					rootpath = context.getResource("/").getPath();
				}
			} catch (MalformedURLException e) {
				e.printStackTrace();
			}
			return rootpath;
		}


    public static Map<String,Long> getAmountAndFee(String amount,String begindate,String enddate,String fee,String ratio)throws Exception{

         long days=TimeUtils.getDateSpaceOfDay(begindate,enddate);
        Map<String,Long> resultmap=new HashMap<String, Long>();
        if(Long.parseLong(amount)<=0){
            resultmap.put("principal",new Long(0));
            resultmap.put("fee",new Long(0));
            resultmap.put("ratio",new Long(0));
        }
        if(days==0){
            resultmap.put("principal",new Long(amount));
            resultmap.put("fee",new Long(0));
            resultmap.put("ratio",new Long(0));
        }else{
            double amountdouble=new Double(amount);
            BigDecimal jishu=new BigDecimal("1");
            if(!CommonUtils.isEmpty(fee)){
                jishu=jishu.add(new BigDecimal(fee).divide(new BigDecimal(100)).multiply(new BigDecimal(days)));
            }
            if(!CommonUtils.isEmpty(ratio)){
                jishu=jishu.add(new BigDecimal(ratio).divide(new BigDecimal(100)).multiply(new BigDecimal(days)));
            }
            BigDecimal decimal=(new BigDecimal(amount).divide(jishu,0,BigDecimal.ROUND_HALF_UP));
            long principalong= decimal.longValue();
            BigDecimal radiodecimal=new BigDecimal("0");
            if(!CommonUtils.isEmpty(fee)){
                radiodecimal=  radiodecimal.add(new BigDecimal(fee));
            }
            if(!CommonUtils.isEmpty(ratio)){
                radiodecimal=radiodecimal.add(new BigDecimal(ratio));
            }
            BigDecimal feedecimal=  (new BigDecimal(amount).subtract(decimal)).multiply(new BigDecimal(fee)).divide(radiodecimal,0,BigDecimal.ROUND_HALF_UP);
            long feelong=feedecimal.longValue();
            long ratiolong=new Long(amount)-principalong-feelong;
            resultmap.put("principal",principalong);
            resultmap.put("fee",feelong);
            resultmap.put("ratio",ratiolong);
        }
        return resultmap;
    }
    
    /**
     * 对集合做sum计算
     * @param toCalc
     * @return
     */
    public  static double sumCollection(List<Double> toCalc){
    	double sum=0;
    	for(double num:toCalc){
    		sum=num+sum;
    	}
    	return sum;
    }
    
    /**
     * 创建Mock 实例
     * @param clazz
     * @param excludeFieldNames
     * @return
     */
    public static <T> T creatRandomObject(Class<T> clazz, String... excludeFieldNames) {  
        T obj = null;  
        try {  
            obj = clazz.newInstance();  
            BeanInfo beanInfo = Introspector.getBeanInfo(clazz);
            PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();  
            for (PropertyDescriptor descriptor : propertyDescriptors) {  
                if ("class".equals(descriptor.getName()) || ArrayUtils.contains(excludeFieldNames, descriptor.getName())) {  
                    continue;
                }  
                if (BeanUtils.isSimpleValueType(descriptor.getPropertyType()) && !descriptor.getPropertyType().getName().equals("java.util.Date")) {  
                    Object value = ConvertUtils.convert(RandomStringUtils.random(1, false, true), descriptor.getPropertyType());  
                    Method writeMethod = descriptor.getWriteMethod();  
                    if (writeMethod != null) {  
                        writeMethod.invoke(obj, value);  
                    }  
                }  
            }  
        } catch (Exception e) {  
        	e.printStackTrace();
        }  
        return obj;  
    }

    /**
     * 直接输出 Result
     * @param response
     * @param result
     * @throws IOException
     */
    public static void  sendJOSNResponse(HttpServletResponse response,Result result) throws IOException{
        response.getWriter().write(JSONUtils.toJSONString(result));
    }
    
    /**
     * 
     * @param originName
     * @param newPath
     * @return
     */
    public static Result buildUploadResult(String originName,String newPath,String downloadUrl){
    	Map<String,String> ret=new HashMap<String,String>();
    	ret.put("originName", originName);
    	ret.put("newPath", newPath);
    	ret.put("downloadUrl", downloadUrl);
    	return new Result(true,ret);
    }

    /**
     * 上传完成后，还回path
     * @param request
     * @param response
     * @param file
     * @param uploadDir
     * @throws IOException
     */
    public static  Result getPathUploadedFile(HttpServletRequest request, HttpServletResponse response, MultipartFile file,String uploadDir) throws IOException {
        response.setContentType("text/html");
        response.setCharacterEncoding(Constants.ENCODING);
        if (null == file) {
            return new Result(Status.ERROR, "没有文件！");
        }
        String filename = file.getOriginalFilename();
        long size = file.getSize();
        String filePath = "";
        try {
            String storeDir = FileUploadUtils.getDefaultBaseDir() + File.separator + uploadDir;
            String url = FileUploadUtils.upload(request, storeDir, file,
                    FileUploadUtils.DEFAULT_ALLOWED_EXTENSION, FileUploadUtils.defaultMaxSize, false);

            filePath = uploadDir + File.separator + FileUploadUtils.getFileNameFromPath(url);

        } catch (FileUploadBase.FileSizeLimitExceededException e) {
            return new Result(Status.ERROR, filename + "文件过大，" + size);
        } catch (BusinessException e) {
            LogUtils.error(log, e, e.getMessage());
            return new Result(Status.ERROR, "上传文件失败，请重试，%s",e.getMessage());
        }
        return new Result(Status.OK,filePath);
    }
    
    public static List<Pair> beanValid(Object obj){
    	List<Pair> ret=new ArrayList<Pair>();
    	ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); 
        Validator validator = factory.getValidator(); 
        Set<ConstraintViolation<Object>> violations = validator.validate(obj);
        for(ConstraintViolation cv: violations){
        	ret.add(Pair.of(cv.getPropertyPath().toString(), cv.getMessage()));
        }
        
        return ret;
    }
    
    public static List<Pair> beanValid(Object obj, List<String> validFieldNames){
    	List<Pair> ret=new ArrayList<Pair>();
    	ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); 
        Validator validator = factory.getValidator(); 
        Set<ConstraintViolation<Object>> violations = validator.validate(obj);
        for(ConstraintViolation cv: violations){
        	if (!validFieldNames.contains(cv.getPropertyPath().toString()))
        		continue;
        	
        	ret.add(Pair.of(cv.getPropertyPath().toString(), cv.getMessage()));
        }
        
        return ret;
    }
    
    
    /**
	 * 返回json格式的提示
	 * 
	 * @param response
	 * @param result
	 * @return
	 */
    public static void sendResponseMsg(HttpServletResponse response,Result result) {
		response.setCharacterEncoding(Constants.ENCODING);
		response.setContentType("text/html;charset=UTF-8");
		OutputStream out;
		try {
			out = response.getOutputStream();
			PrintWriter pw = new PrintWriter(new OutputStreamWriter(out,
					Constants.ENCODING));
			pw.print(JSONUtils.toJSONString(result));
			pw.flush();
			pw.close();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}
    
    /**
     * 手机号mask
     * @param cardNo
     * @return
     */
    public static String maskMobile(String cardNo) {
		String pre=cardNo.substring(0,3);
		String end=cardNo.substring(cardNo.length()-4);
		String middle=dup("*", cardNo.length()-7);
		String maskmobile = pre+middle+end;
		return maskmobile;
	}  
    
    /**
	 * 提取集合中的对象的一个属性(通过Getter函数), 组合成List.
	 * 
	 * @param collection 来源集合.
	 * @param propertyName 要提取的属性名.
	 */
	@SuppressWarnings("unchecked")
	public static List extractToList(final Collection collection, final String propertyName) {
		List list = new ArrayList(collection.size());

		try {
			for (Object obj : collection) {
				list.add(PropertyUtils.getProperty(obj, propertyName));
			}
		} catch (Exception e) {
			throw ReflectUtils.convertReflectionExceptionToUnchecked(e);
		}

		return list;
	}
	
	/**
	 * 提取集合中的对象的一个属性(通过Getter函数), 组合成由分割符分隔的字符串.
	 * 
	 * @param collection 来源集合.
	 * @param propertyName 要提取的属性名.
	 * @param separator 分隔符.
	 */
	public static String extractToString(final Collection collection, final String propertyName, final String separator) {
		List list = extractToList(collection, propertyName);
		return StringUtils.join(list, separator);
	}
	
	/**
	 * 获取当前请求对象
	 * @return
	 */
	public static HttpServletRequest getRequest(){
		try{
			return ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
		}catch(Exception e){
			return null;
		}
	}
	 
	/**
	 * 获取授权主要对象
	 */
	public static Subject getSubject(){
		return SecurityUtils.getSubject();
	}
	
	
	public static String getFenByLong(long amount) {
		double amountdouble = new Double(amount);
		DecimalFormat df = new DecimalFormat("0.00");
		return df.format(amountdouble/100);
	}
	
	public static String getFenByString(String amountStr) {
		long amount = getLong(amountStr);
		double amountdouble = new Double(amount);
		DecimalFormat df = new DecimalFormat("0.00");
		return df.format(amountdouble/100);
	}
	
	/**
	 * 序列化对象
	 * @param object
	 * @return
	 */
	public static byte[] serialize(Object object) {
		ObjectOutputStream oos = null;
		ByteArrayOutputStream baos = null;
		try {
			if (object != null){
				baos = new ByteArrayOutputStream();
				oos = new ObjectOutputStream(baos);
				oos.writeObject(object);
				return baos.toByteArray();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 序列化对象
	 * 
	 * @param object
	 * @return
	 */
	public static String serializeToString(Object object, String charset) {
		try {
			ByteArrayOutputStream bo = new ByteArrayOutputStream();
			ObjectOutputStream so = new ObjectOutputStream(bo);
			so.writeObject(object);
			so.flush();
			// This encoding induces a bijection between byte[] and String
			// (unlike UTF-8)
			return bo.toString(charset);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	/**
	 * 序列化VO 到目录
	 * 
	 * @param vo
	 * @param key
	 */
	public static void serializedVo(File path, Object vo, String key) {
		try {
			File temp = new File(path, key);
			FileOutputStream fout = new FileOutputStream(temp);
			ObjectOutputStream oos = new ObjectOutputStream(fout);
			oos.writeObject(vo);
			oos.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public static void serializedVo(File file, Object o) throws IOException {
		FileOutputStream fo = null;
		ObjectOutputStream out = null;
		try {

			fo = new FileOutputStream(file);
			out = new ObjectOutputStream(fo);

			out.writeObject(o); 
			// 写入customer对象

		} catch (FileNotFoundException e1) {
			e1.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			if (null != out) {

				out.close();

			}

		}

	}

	/**
	 * Deserialize any object
	 * 
	 * @param str
	 * @param charset
	 * @return
	 */
	public static Object deserialize(String str, String charset) {
		// deserialize the object
		try {
			// This encoding induces a bijection between byte[] and String
			// (unlike UTF-8)
			byte b[] = str.getBytes(charset);
			ByteArrayInputStream bi = new ByteArrayInputStream(b);
			ObjectInputStream si = new ObjectInputStream(bi);
			return si.readObject();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return str;
	}

	/**
	 * Deserialize any object
	 * 
	 * @param str
	 * @return
	 */
	public static Object deserialize(String str) {
		return deserialize(str,"ISO-8859-1");
	}
	
	/**
	 * 反序列化对象
	 * @param bytes
	 * @return
	 */
	public static Object unserialize(byte[] bytes) {
		ByteArrayInputStream bais = null;
		try {
			if (bytes != null && bytes.length > 0){
				bais = new ByteArrayInputStream(bytes);
				ObjectInputStream ois = new ObjectInputStream(bais);
				return ois.readObject();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	/**
	 * 反序列化对象文件得到vo对象，泛型
	 * 
	 * @param key
	 * @return
	 */
	public static <T> T deSerializedVo(File key) {
		T voRes = null;
		try {
			FileInputStream fin = new FileInputStream(key);
			ObjectInputStream ois = new ObjectInputStream(fin);
			voRes = (T) ois.readObject();
            fin.close();
			ois.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return voRes;
	}
	
	/**
     * 判断访问URI是否是静态文件请求
	 * @throws Exception 
     */
    public static boolean isStaticFile(String uri){
		if (StringUtils.endsWithAny(uri, staticFiles)){
			return true;
		}
		return false;
    }
    
    /**
     * ajax request
     * @param httpServletRequest
     * @return
     */
    public static boolean isAjaxRequest(HttpServletRequest httpServletRequest) {
		return "XMLHttpRequest".equalsIgnoreCase(httpServletRequest  
                .getHeader("X-Requested-With"));
	}

	/**
	 * session may null
	 * @return
	 */
	public static Session getSession(){
		return  getSession(false);
	}

	/**
	 * session may null
	 * @return
	 */
	public static Session getSession(boolean create){
		Subject subject = SecurityUtils.getSubject();
		return  subject.getSession(create);
	}
	
	/**
	 * session not null
	 * @return
	 */
	public static Session getShiroSession(){
		try{
			Subject subject = SecurityUtils.getSubject();
			Session session = subject.getSession(false);
			if (session == null){
				session = subject.getSession();
			}
			if (session != null){
				return session;
			}
		}catch (InvalidSessionException e){
			
		}
		return null;
	}

	/**
	 * 仅限保理系统访问
	 * @return
	 */
	public static User getSysUser(){
		User user=null;
		Principal principal = getPrincipal();
		if (principal!=null){
			 user = UserUtils.getUser();
		}
		return user;
	}

	/**
	 * 获取登录用户id
	 */
	public static int getLoginUserId(){
		Principal principal = getPrincipal();
		if(null==principal||null==principal.getId()){
			throw new ControllerException("长时间未操作，请重新登录");
		}
		return Integer.parseInt(principal.getId());
	}

	/**
	 * 获取当前登录者对象
	 */
	public static Principal getPrincipal(){
		try{
			Subject subject = SecurityUtils.getSubject();
			Principal principal = (Principal)subject.getPrincipal();
			if (principal != null){
				return principal;
			}
		}catch (UnavailableSecurityManagerException e) {
			
		}catch (InvalidSessionException e){
			
		}
		return null;
	}

	/**
	 * 获取登录用户
	 */
	public static SessionUser getSessionUser(HttpServletRequest request){
		Session session=getSession();
		if(null==session){
			throw new ControllerException("长时间未操作，请重新登录");
		}
		SessionUser data=(SessionUser)session.getAttribute(Constants.SESSION_LOGINUSER);
		if(null==data){
			throw new ControllerException("长时间未操作，请重新登录");
		}
		return data;
	}


	/**
	 * Hex解码.
	 */
	public static byte[] decodeHex(String input) {
		try {
			return Hex.decodeHex(input.toCharArray());
		} catch (DecoderException e) {
			throw unchecked(e);
		}
	}

	/**
	 * URL 解码, Encode默认为UTF-8. 
	 */
	public static String urlEncode(String part) {
		try {
			return URLEncoder.encode(part, Constants.ENCODING);
		} catch (UnsupportedEncodingException e) {
			throw unchecked(e);
		}
	}

	/**
	 * URL 解码, Decode默认为UTF-8. 
	 */
	public static String urlDecode(String part) {
		try {
			return URLDecoder.decode(part, Constants.ENCODING);
		} catch (UnsupportedEncodingException e) {
			throw unchecked(e);
		}
	}
	
	/**
	 * 将CheckedException转换为UncheckedException.
	 */
	public static RuntimeException unchecked(Exception e) {
		if (e instanceof RuntimeException) {
			return (RuntimeException) e;
		} else {
			return new RuntimeException(e);
		}
	}
	
	public static String getMessageByLeft1000(String message) {
		if(isEmpty(message))
			return "";
		
		if (message.length() <= 1000) 
			return message;
			
		return StringUtils.substring(message, 0, 1000);
	}
	
	public static String getMessageByLength(String message, int strlength) {
		if (message.length() <= strlength) 
			return message;
			
		return StringUtils.substring(message, 0, strlength);
	}
	
	public static String trimHtml(String old){
		if(CommonUtils.isEmpty(old)){
			return old;
		}else{
			String newstr = old.trim().replace("\n", "");
			return newstr;
		}
		
	}

    public static double getYuanByLong(Long amount){
        BigDecimal amountdecimal=new BigDecimal(amount).divide(new BigDecimal(100));
        return amountdecimal.doubleValue();
    }

   public static boolean isWorkTime(){
       Date d=new Date();
       int hours=d.getHours();
     //  Calendar  c=new  GregorianCalendar();
      // int hours = c.get(Calendar.HOUR);
       if(hours>=9&&hours<=17){

           return true;
       }else if(hours==8){
        //   int miniture=c.get(Calendar.MINUTE);
           int miniture=d.getMinutes();
           if(miniture>=30){
               return true;
           }
       }
       return false;
   }
   
   
   public static boolean canToJSON(Class clazz){
	  return !(clazz.isPrimitive() || ClassUtils.wrapperToPrimitive(clazz) != null ||clazz=="".getClass());
   }

	/**
	 * 重请求获取RSA_PUBLICKEY(when deploy war )
	 * 过期后 退出系统
	 * @param request
     */
	public static void checkRSAExpired(HttpServletRequest request){
		String publicKey=request.getParameter("RSA_PUBLICKEY");
		 if(StringUtils.isNotEmpty(publicKey)){
			String cPublicKey = new String(Hex.encodeHex(RSAUtils.getDefaultPublicKey().getModulus().toByteArray()));
			if(!publicKey.equals(cPublicKey)){
				Subject subject = CommonUtils.getSubject();
				if (subject != null && subject.isAuthenticated()) {
					subject.logout();
				}
				throw new BusinessException("您好，安全信息过期，请重新登陆");
			}
		 }
	}

	public static boolean  isIE(HttpServletRequest request){
		String userAgent = request.getHeader("User-Agent");
		boolean isIE = (userAgent != null)
				&& (userAgent.toLowerCase().indexOf("msie") != -1 || userAgent.toLowerCase().indexOf("trident") != -1);
	   return isIE;
	}

	public static String mapToString(Map<String, String> map) {
		StringBuilder stringBuilder = new StringBuilder();

		for (String key : map.keySet()) {
			if (stringBuilder.length() > 0) {
				stringBuilder.append("&");
			}
			String value = map.get(key);
			try {
				stringBuilder.append((key != null ? URLEncoder.encode(key, "UTF-8") : ""));
				stringBuilder.append("=");
				stringBuilder.append(value != null ? URLEncoder.encode(value, "UTF-8") : "");
			} catch (UnsupportedEncodingException e) {
				throw new RuntimeException("This method requires UTF-8 encoding support", e);
			}
		}

		return stringBuilder.toString();
	}

	/**
	 * parse key-value pair.
	 *
	 * @param str string.
	 * @param itemSeparator item separator.
	 * @return key-value map;
	 */
	private static Map<String, String> parseKeyValuePair(String str, String itemSeparator)
	{
		String[] tmp = str.split(itemSeparator);
		Map<String, String> map = new HashMap<String, String>(tmp.length);
		for(int i=0;i<tmp.length;i++)
		{
			Matcher matcher = KVP_PATTERN.matcher(tmp[i]);
			if( matcher.matches() == false )
				continue;
			map.put(matcher.group(1), matcher.group(2));
		}
		return map;
	}

	public static String getQueryStringValue(String qs, String key) {
		Map<String, String> map = parseQueryString(qs);
		return map.get(key);
	}

	/**
	 * parse query string to Parameters.
	 *
	 * @param qs query string.
	 * @return Parameters instance.
	 */
	public static Map<String, String> parseQueryString(String qs)
	{
		if( qs == null || qs.length() == 0 )
			return new HashMap<String, String>();
		return parseKeyValuePair(qs, "\\&");
	}

	public static List<String> join(Map<String, String> map, String separator) {
		if (map == null) {
			return null;
		}
		List<String> list = new ArrayList<String>();
		if (map == null || map.size() == 0) {
			return list;
		}
		for (Map.Entry<String, String> entry : map.entrySet()) {
			String key = entry.getKey();
			String value = entry.getValue();
			if (value == null || value.length() == 0) {
				list.add(key);
			} else {
				list.add(key + separator + value);
			}
		}
		return list;
	}


	public static Map<String, String> toStringMap(String... pairs) {
		Map<String, String> parameters = new HashMap<String, String>();
		if (pairs.length > 0) {
			if (pairs.length % 2 != 0) {
				throw new IllegalArgumentException("pairs must be even.");
			}
			for (int i = 0; i < pairs.length; i = i + 2) {
				parameters.put(pairs[i], pairs[i + 1]);
			}
		}
		return parameters;
	}

	@SuppressWarnings("unchecked")
	public static <K, V> Map<K, V> toMap(Object ... pairs) {
		Map<K, V> ret = new HashMap<K, V>();
		if (pairs == null || pairs.length == 0) return ret;

		if (pairs.length % 2 != 0) {
			throw new IllegalArgumentException("Map pairs can not be odd number.");
		}
		int len = pairs.length / 2;
		for (int i = 0; i < len; i ++) {
			ret.put((K) pairs[2 * i], (V) pairs[2 * i + 1]);
		}
		return ret;
	}

}
